package com.wondertek.poms.service.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wondertek.oes.sso.common.util.SecurityUtils;
import com.wondertek.poms.common.constant.Constants;
import com.wondertek.poms.common.log.MethodLog;
import com.wondertek.poms.common.vo.PageBean;
import com.wondertek.poms.common.vo.ResultBean;
import com.wondertek.poms.core.feign.SSOFeignClient;
import com.wondertek.poms.core.service.IContentService;
import com.wondertek.poms.core.service.IFirstProductInfoPackageService;
import com.wondertek.poms.core.service.IPcProductPermissionService;
import com.wondertek.poms.core.service.IPrdContService;
import com.wondertek.poms.core.service.IPrdInfoService;
import com.wondertek.poms.core.service.IProductInfoPackageService;
import com.wondertek.poms.core.service.ISecondClassifyService;
import com.wondertek.poms.core.service.ISystemConfigService;
import com.wondertek.poms.core.utils.DateUtil;
import com.wondertek.poms.dao.po.*;
import com.wondertek.poms.dao.pojo.PrdContSelPojo;
import com.wondertek.poms.dao.pojo.SsoGroupPojo;
import com.wondertek.poms.dao.vo.LivePlayVo;
import com.wondertek.poms.dao.vo.NodeVo;
import com.wondertek.poms.dao.vo.PrdContVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api(value = "PrdContController", description = "节目")
@RestController
@RequestMapping(value="/prd-cont")
@Validated
@Slf4j
public class PrdContController {

    @Autowired
    private IPrdContService prdContService;
    @Autowired
    private ISecondClassifyService secondClassifyService;
    @Autowired
    private IContentService contentService;
    @Autowired
    private ISystemConfigService systemConfigService;
    @Autowired
    private IPcProductPermissionService pcProductPermissionService;
    @Autowired
    private IFirstProductInfoPackageService firstProductInfoPackageService;
    @Autowired
    private IProductInfoPackageService productInfoPackageService;
    @Autowired
    private IPrdInfoService prdInfoService;
    @Resource
    private SSOFeignClient ssoFeignClient;

    /**
     * 树形结构-选择类型 1:一级产品
     */
    public static final int TREE_SELECT_TYPE_1 = 1;
    /**
     * 树形结构-选择类型 2:二级产品
     */
    public static final int TREE_SELECT_TYPE_2 = 2;
    /**
     * 树形结构-选择类型 3:商品包
     */
    public static final int TREE_SELECT_TYPE_3 = 3;

    public static final String RESULT = "result";

    /**
     * 节目列表查询
     *
     * @param prdCont 查询参数接收
     * @param page            页数
     * @param rows            记录数
     * @param sord            排序方式
     * @param sidx            排序列
     * @return 分页后的规则列表
     */
    @ApiOperation(value = "节目列表", notes = "节目列表")
    @GetMapping("/list")
    @MethodLog(module = "节目列表")
    public ResultBean list( PrdContSelPojo prdCont,
                            @RequestParam(defaultValue = "1") int page,
                            @RequestParam(defaultValue = "20") int rows,
                            @RequestParam(defaultValue = "desc") String sord,
                            @RequestParam(defaultValue = "c.CREATE_TIME") String sidx) {
        try {
            if( StringUtils.isBlank(prdCont.getProductInfoPackageId()) && StringUtils.isBlank(prdCont.getPrdInfoId())){
                return ResultBean.error("二级产品和商品包至少选一个");
            }
            if(StringUtils.isNotBlank(prdCont.getContentName()) || prdCont.getPrdContId()!=null
                    ||prdCont.getMmsID()!=null || prdCont.getContentId()!=null){
                prdCont.setCreateTimeBegin(null);
                prdCont.setCreateTimeEnd(null);
                prdCont.setLastModifyTimeBegin(null);
                prdCont.setLastModifyTimeEnd(null);
            }
            Page<PrdContVo> pages = prdContService.findAll(prdCont,page,rows,sord,sidx);
            return PageBean.ok(pages.getTotalPages(), pages.getTotalElements(), pages.getContent());
        }catch (Exception e){
            return ResultBean.error(e.toString());
        }
    }

    /**
     * 节目详情查询
     *
     * @param prdContId 节目id
     * @return 分页后的规则列表
     */
    @ApiOperation(value = "节目详情查询", notes = "节目详情查询")
    @GetMapping("/get-details")
    @MethodLog(module = "节目详情")
    public ResultBean getDetails(@NotNull(message = "节目id不能为空")
                                 @RequestParam Long prdContId) {
        try {
            return ResultBean.ok(prdContService.findPrdContDetailVoById(prdContId));
        }catch (Exception e){
            return ResultBean.error(e.toString());
        }
    }

    /**
     * 节目详情查询
     *
     * @param prdContId 节目id
     * @return 分页后的规则列表
     */
    @ApiOperation(value = "节目详情图片查询", notes = "节目详情图片查询")
    @GetMapping("/get-details-img")
    @MethodLog(module = "节目详情图片查询")
    public ResultBean findPrdContDetailImgById(Long prdContId,Long contentId) throws IOException {
            return prdContService.findPrdContDetailImgById(prdContId,contentId);
    }

    /**
     * 查询产品和商品包树结构列表
     * @return 树结构
     */
    @ApiOperation(value = "产品和商品包树结构", notes = "产品和商品包树结构")
    @GetMapping("/list-prd-info-cont")
    @ResponseBody
    public ResultBean getPreviewList(){
        try {
            return ResultBean.ok(prdContService.findPrdAndCont());
        }catch (Exception e){
            return ResultBean.error(e.toString());
        }
    }

    /**
     * 查询直播节目列表 预告
     * @param prdInfoId 商品包id
     * @param contentId 内容id
     * @param contentFrom 内容形态
     * @return 直播节目列表
     */
    @ApiOperation(value = "单集预告", notes = "单集预告")
    @GetMapping("/get-preview-list")
    @ResponseBody
    public ResultBean getPreviewList(String contentId, String prdInfoId,String contentFrom){
        try {
            if(StringUtils.isNotBlank(contentFrom)){
                contentFrom="预告";
            }
            return ResultBean.ok(prdContService.getSerialList(contentId,prdInfoId,contentFrom));
        }catch (Exception e){
            return ResultBean.error(e.toString());
        }
    }

    /**
     * 查询直播节目列表
     * @param prdInfoId 商品包id
     * @param contentId 内容id
     * @return 直播节目列表
     */
    @ApiOperation(value = "视频列表", notes = "视频列表")
    @GetMapping("/get-video-list")
    @ResponseBody
    public ResultBean getPreviewList(String contentId, String prdInfoId){
        try {
            return ResultBean.ok(prdContService.getSerialList(contentId,prdInfoId,null));
        }catch (Exception e){
            return ResultBean.error(e.toString());
        }
    }

    /**
     * 查询直播节目列表
     * @param prdInfoId 商品包id
     * @param contentId 内容id
     * @return 直播节目列表
     */
    @ApiOperation(value = "直播节目列表", notes = "直播节目列表")
    @GetMapping("/get-live-play-list")
    @ResponseBody
    public ResultBean getLivePlayList( String prdInfoId,String contentId,String dateTime) {
        if(StringUtils.isBlank(contentId)){
            return ResultBean.error("内容id不能为空");
        }
        if(StringUtils.isBlank(dateTime)){
            return ResultBean.error("播放日期不能为空");
        }
        String endTime="";
        if (StringUtils.isNotBlank(dateTime)) {
            dateTime=dateTime.substring(0, 10);
            Date tempDate= DateUtil.parseDate("yyyy-MM-dd", dateTime);
            Calendar c = Calendar.getInstance();
            c.setTime(tempDate);
            c.add(Calendar.DAY_OF_MONTH, 3);
            tempDate = c.getTime();
            endTime = DateUtil.formatDate("yyyy-MM-dd HH:mm", tempDate);
        }
        List<LivePlayVo> list =null;
        try {
            return ResultBean.ok(prdContService.findLivePlayList(prdInfoId,contentId,dateTime,endTime));
        }catch (Exception e){
            return ResultBean.error(e.toString());
        }
    }

     /** 查询直播节目【单】列表
     *@author gaozhengxing gaozhenghang@wondertek.com.cn
     *@date 2020/12/10 10:58
     *@param prdContId 节目id
     *@param contentId 内容id
     *@param playDay 直播日期
     * @return 直播节目"单"列表
     */
    @ApiOperation(value = "直播节目【单】列表", notes = "直播节目【单】列表")
    @GetMapping("/get-live-playbill-list")
    @ResponseBody
    public ResultBean getLivePlaybillList(String prdContId, String contentId, String playDay) {
        try {
            return ResultBean.ok(prdContService.findLivePlaybillList(prdContId,contentId,playDay));
        }catch (Exception e){
            return ResultBean.error(e.toString());
        }
    }



    /**
     * 节目详情查询
     *
     * @param prdContId 节目id
     * @return 分页后的规则列表
     */
    @ApiOperation(value = "补全缺集", notes = "补全缺集")
    @GetMapping("/add-miss")
    @ResponseBody
    public ResultBean addMiss(
            @RequestParam Long prdContId) {
        try {
            return prdContService.addMiss(prdContId);
        }catch (Exception e){
            return ResultBean.error(e.toString());
        }
    }

    /**
     * 紧急配置-设为紧急
     * @param prdContIds 节目id
     * @return 设置结果
     */
    @ApiOperation(value = "设为紧急",notes = "设为紧急")
    @PutMapping("/set-emergency")
    @ResponseBody
    public ResultBean setEmergency(@RequestParam String prdContIds){
        String[] idArray = prdContIds.split(",");
        List<Long> ids = Arrays.stream(idArray).distinct().map(Long::parseLong).collect(Collectors.toList());
        try {
            prdContService.batchUpdateIsEmergencyById("1", ids);
        }catch (Exception e){
            ResultBean.error(e.toString());
        }
        return ResultBean.ok();
    }

    /**
     * 紧急配置-取消紧急
     * @param prdContIds 节目id
     * @return 设置结果
     */
    @ApiOperation(value = "取消紧急",notes = "取消紧急")
    @PutMapping("/unset-emergency")
    @ResponseBody
    public ResultBean unsetEmergency(@RequestParam String prdContIds){
        String[] idArray = prdContIds.split(",");
        List<Long> ids = Arrays.stream(idArray).distinct().map(Long::parseLong).collect(Collectors.toList());
        try {
            prdContService.batchUpdateIsEmergencyById("0", ids);
        }catch (Exception e){
            ResultBean.error(e.toString());
        }
        return ResultBean.ok();
    }

    /**
     * 扩展属性
     * @param contentId 内容id
     * @return 查询结果
     */
    @ApiOperation(value = "扩展属性",notes = "扩展属性")
    @GetMapping("/get-second-classifys")
    @ResponseBody
    public ResultBean getSecondClassifys(String contentId){
        List<SecondClassify> lists = secondClassifyService.findAllByContentId(contentId);
        if(lists!=null) {
            List<SecondClassify> result = new ArrayList<>(lists.stream().collect(Collectors.toMap(SecondClassify::getClassifyKey, v -> v, (v1, v2) -> {
                v1.setClassifyValue(v1.getClassifyValue() + ";" + v2.getClassifyValue());
                return v1;
            })).values());
            return ResultBean.ok(result);
        }else {
            return ResultBean.ok();
        }
    }

    /**
     * 正文明细
     * @param contentId 内容id
     * @return ok
     */
    @ApiOperation(value = "正文明细",notes = "正文明细")
    @GetMapping("/get-text-detail")
    @ResponseBody
    public ResultBean getTextDetail(String contentId) {
        InputStream inputStream;
        String localPath = "";
        Content content = contentService.findByContentId(contentId);
        String metadataPathOption ="0";
        if(content!=null && content.getId()!=null) {
            SystemConfig config = systemConfigService.findAllBykey("DATA_STORE_PATH_OPTION");
            if(config != null){
                metadataPathOption = config.getValue();
            }
            if("1".equals(metadataPathOption)) {
                localPath = systemConfigService.findAllBykey("poms_syncFile_basePath").getValue() + "/zhengshi" +  contentIdToPath(contentId) + "news/news.html";
            }else {
                localPath = systemConfigService.findAllBykey("syncFile_basePath").getValue() + "/zhengshi" + contentIdToPath(contentId) + "news/news.html";
            }
        }

        File htmlFile = new File(localPath);
        if(htmlFile.exists() && htmlFile.isFile()) {
            try {
                inputStream = new FileInputStream(htmlFile);
                return ResultBean.ok(IoUtil.readUtf8(inputStream));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return ResultBean.error(e.getMessage());
            }
        }
        return ResultBean.error("文件未找到");
    }

    public String contentIdToPath(String contentId) {
        if (contentId == null || contentId.equals("") || contentId.trim().length() != 10) {
            throw new RuntimeException();
        }
        return "/" + contentId.substring(0, 4) + "/" + contentId.substring(4, 7) + "/" + contentId.substring(7, 10) + "/" + contentId + "/";
    }

    /**
     * 只过滤出该用户的全量权限树
     *
     * @param
     * @return
     */
    @SuppressWarnings("DanglingJavadoc")
    @GetMapping(value = "/get-user-full-tree")
    public ResultBean getUserFullTree(HttpServletRequest request,String ugid) throws IOException {

        /******************************************************************************************************************
         *
         * 用户权限
         *
         ******************************************************************************************************************/
        String currentUserId= SecurityUtils.getCurrentUser().getUserId().toString();
        String currentUserName = SecurityUtils.getCurrentUserName();
        log.info("getUserFullTree=========当前登录的用户ID和当前登录用户名称为======currentUserId={},currentUserName={}", currentUserId, currentUserName);
        PcProductPermission pc = new PcProductPermission();
        pc.setUgid(0L);
        pc.setDeleted(Constants.DELETE_0);
        pc.setUserType(1);
        //根据用户获取的权限
        List<PcProductPermission> pcProductPermissions = pcProductPermissionService.findAll(Example.of(pc));


        if(StringUtils.isNotBlank(ugid)){

        }
        /******************************************************************************************************************
         *
         * 组权限
         *
         ******************************************************************************************************************/
        Cookie[] cookies = request.getCookies();
        String value = null;
        for (Cookie element : cookies) {
            String name = element.getName();
            if (StringUtils.equals(name, "accessToken")) {
                value = element.getValue();
                break;
            }
        }
        if (StringUtils.isBlank(value)) {
            ResultBean.error("根据用户组id查询用户id列表失败");
        }
        String userIdByGroupId = ssoFeignClient.getGroupInfoByUser(value);
        JSONObject jsonObject = JSON.parseObject(userIdByGroupId);
        if (!"90000".equals(jsonObject.getString("code"))) {
            return PageBean.error(jsonObject.getString("message"));
        }
        String result = jsonObject.getString(RESULT);
        ObjectMapper mapper = new ObjectMapper();
        List<SsoGroupPojo> groupList = mapper.readValue(result, new TypeReference<List<SsoGroupPojo>>() {
        });
        log.info("当前用户的群组列表|{}", groupList);

        if (CollectionUtil.isNotEmpty(groupList)) {
            for (SsoGroupPojo group : groupList) {
                Long groupId = group.getGroupId();
                //去权限表查组的权限
                PcProductPermission pcParam = new PcProductPermission();
                pcParam.setUgid(groupId);
                pcParam.setDeleted(Constants.DELETE_0);
                pcParam.setUserType(2);
                //根据用户组获取的权限
                List<PcProductPermission> pcProductPermissionGroups = pcProductPermissionService.findAll(Example.of(pcParam));
                pcProductPermissions.addAll(pcProductPermissionGroups);
            }
        }


        //获取全量产品树
        List<NodeVo> nodeList = getFullNode();
        Map<String, NodeVo> nodes = new LinkedHashMap<>();
        for (NodeVo node : nodeList) {
            nodes.put(node.getId(), node);
        }
        if (!"administrator".equals(currentUserName)) {
            //过滤出该用户的全量权限树
            List<NodeVo> UserNodeVoList = new ArrayList<>();
            Map<String, NodeVo> treeNodeVos = new LinkedHashMap<>();
            for (PcProductPermission permission : pcProductPermissions) {
                //保存一级产品节点
                if (1 == permission.getPrdLevel()) {
                    //获取一级节点
                    NodeVo firNodeVo = nodes.get("fir-" + permission.getFsPrdId());
                    log.info("firNodeVo====:{}", firNodeVo);
                    UserNodeVoList.add(firNodeVo);
                }
                //保存二级节点
                if (2 == permission.getPrdLevel()) {
                    //获取当前二级节点
                    NodeVo secNodeVo = nodes.get("two-" + permission.getFsPrdId());
                    log.info("secNodeVo====={}", secNodeVo);
                    UserNodeVoList.add(secNodeVo);

                }
                if (3 == permission.getPrdLevel()) {
                    //添加三级节点
                    NodeVo thrNodeNo = nodes.get("thr-" + permission.getFsPrdId());
                    log.info("thrNodeNo===={}", thrNodeNo);
                    UserNodeVoList.add(thrNodeNo);

                }
            }
            log.info("getUserFullTree =======UserNodeVoList=={}", UserNodeVoList.toString());
            if (!UserNodeVoList.isEmpty()) {
                for (NodeVo node : UserNodeVoList) {
                    treeNodeVos.put(node.getId(), node);
                }
            } else {
                return ResultBean.error("该用户没有配置产品展现的菜单权限，请联系管理员配置产品展现的菜单权限");
            }
            log.info("getUserFullTree =======treeNodeVos==={}", treeNodeVos.toString());
            if (!treeNodeVos.isEmpty()) {
                return ResultBean.ok(getNodeVoJson("0", treeNodeVos));
            }
        }
        log.info("nodes====={}", toString());
        return ResultBean.ok(getNodeVoJson("0", nodes));
    }
    /**
     * 递归处理   数据库树结构数据->树形json
     *
     * @param nodeId
     * @param nodes
     * @return
     */
    public List<NodeVo> getNodeVoJson(String nodeId, Map<String, NodeVo> nodes) {
        //当前层级当前node对象
//        NodeVo cur = nodes.get(nodeId);
        //当前层级当前点下的所有子节点
        List<NodeVo> childList = getChildNodeVos(nodeId, nodes);
        List<NodeVo> nodeVos = new ArrayList<>();
        for (NodeVo node : childList) {
            NodeVo o = NodeVo.builder().id(node.getId())
                    .isShow(node.getIsShow())
                    .parentId(node.getParentId())
                    .type(node.getType())
                    .path(node.getPath())
                    .name(node.getName()).build();
            List<NodeVo> childs = getNodeVoJson(node.getId(), nodes);  //递归调用该方法
            if (!childs.isEmpty()) {
                o.setChildren(childs);
            }
            nodeVos.add(o);
        }
        return nodeVos;
    }

    /**
     * 获取全量树
     *
     * @return
     */
    public List<NodeVo> getFullNode() {
        // 一级产品列表
        List<FirstProductInfoPackage> pfs = firstProductInfoPackageService.findAll();
        //查询poms的二级产品包
        List<ProductInfoPackage> pss = productInfoPackageService.getAllPomsProductInfoPackage();
        //保存所有节点
        List<NodeVo> nodeVoList = new ArrayList<>();
        pfs.forEach(pf -> {
            String path = pf.getFirstProductName();
            NodeVo first = NodeVo.builder()
                    .id("fir-" + pf.getFirstProductId())
                    .type(TREE_SELECT_TYPE_1)
                    .name(pf.getFirstProductName())
                    .parentId("0")
                    .isShow(0)
                    .path(path)
                    .build();

            //筛选二级产品
            getSecondInProductFirst(pss, pf.getFirstProductId(), nodeVoList, path);

            //first.setChildren(childSecond);
            nodeVoList.add(first);
        });
        return nodeVoList;
    }

    /**
     * 把符合一级产品的二级产品过滤出来
     *
     * @param pss         二级产品列表
     * @param id          一级产品ID
     * @param nodeVoList  一级产品列表
     * @param path_parent 父节点路径（对应一级节点路径）
     */

    private void getSecondInProductFirst(List<ProductInfoPackage> pss, Long id, List<NodeVo> nodeVoList, String path_parent) {
        pss.forEach(ps -> {
            String path = path_parent + "/" + ps.getProductInfoPackageName();
            if (id.equals(ps.getFirstProductInfoPackageId())) {
                NodeVo second = NodeVo.builder()
                        .id("two-" + ps.getProductInfoPackageId())
                        .type(TREE_SELECT_TYPE_2)
                        .name(ps.getProductInfoPackageName())
                        .parentId("fir-" + id)
                        .isShow(0)
                        .path(path)
                        .build();

                nodeVoList.add(second);
                getPrdInfoInProductSecond(ps, nodeVoList, path);
            }

        });
    }

    /**
     * 查询在二级产品下存在的商品包
     *
     * @param ps          二级产品包
     * @param nodeVoList  保存的节点
     * @param path_parent 对应的二级节点路径
     */
    private void getPrdInfoInProductSecond(ProductInfoPackage ps, List<NodeVo> nodeVoList, String path_parent) {
        //获取poms使用的商品包
        List<PrdInfo> pis = prdInfoService.findPrdInfoInPackageId(ps.getProductInfoPackageId(),2);
        pis.forEach(pi -> {
            String path = path_parent + "/" + pi.getName();
            NodeVo third = NodeVo.builder()
                    .id("thr-" + pi.getPrdInfoId())
                    .type(TREE_SELECT_TYPE_3)
                    .name(pi.getName())
                    .parentId("two-" + ps.getProductInfoPackageId())
                    .isShow(0)
                    .path(path)
                    .build();
            nodeVoList.add(third);
        });
    }

    /**
     * 获取当前节点的所有子节点
     *
     * @param nodeId
     * @param nodes
     * @return
     */
    public List<NodeVo> getChildNodeVos(String nodeId, Map<String, NodeVo> nodes) {
        List<NodeVo> list = new ArrayList<>();
        for (NodeVo value : nodes.values()) {
            if (nodeId.equals(value.getParentId())) {
                list.add(value);
            }
        }

        return list;
    }

}
